﻿/*
* jQuery plugin: fieldSelection - v0.1.0 - last change: 2006-12-16
* (c) 2006 Alex Brem <alex@0xab.cd> - http://blog.0xab.cd
*/

(function () {
	var fieldSelection = {
		getSelection: function () {
			var e = this.jquery ? this[0] : this;

			return (
			/* mozilla / dom 3.0 */
				('selectionStart' in e && function () {
					var l = e.selectionEnd - e.selectionStart;
					return {
						start: e.selectionStart,
						end: e.selectionEnd,
						length: l,
						text: e.value.substr(e.selectionStart, l)
					};
				})

			/* exploder */
				|| (document.selection && function () {
					e.focus();

					var r = document.selection.createRange();
					if (r == null) {
						return {
							start: 0,
							end: e.value.length,
							length: 0
						};
					}

					var re = e.createTextRange();
					var rc = re.duplicate();
					re.moveToBookmark(r.getBookmark());
					rc.setEndPoint('EndToStart', re);

					// IE bug - it counts newline as 2 symbols when getting selection coordinates,
					//  but counts it as one symbol when setting selection
					var rcLen = rc.text.length,
						i,
						rcLenOut = rcLen;
					for (i = 0; i < rcLen; i++) {
						if (rc.text.charCodeAt(i) == 13) rcLenOut--;
					}
					var rLen = r.text.length,
						rLenOut = rLen;
					for (i = 0; i < rLen; i++) {
						if (r.text.charCodeAt(i) == 13) rLenOut--;
					}

					return {
						start: rcLenOut,
						end: rcLenOut + rLenOut,
						length: rLenOut,
						text: r.text
					};
				})

			/* browser not supported */
				|| function () {
					return {
						start: 0,
						end: e.value.length,
						length: 0
					};
				}

			)();

		},

		setSelection: function (start, end) {
			var e = document.getElementById($(this).attr('id')); // I don't know why... but $(this) don't want to work today :-/
			if (!e) {
				return $(this);
			} else if (e.setSelectionRange) { /* WebKit */
				e.focus(); e.setSelectionRange(start, end);
			} else if (e.createTextRange) { /* IE */
				var range = e.createTextRange();
				range.collapse(true);
				range.moveEnd('character', end);
				range.moveStart('character', start);
				range.select();
			} else if (e.selectionStart) { /* Others */
				e.selectionStart = start;
				e.selectionEnd = end;
			}

			return $(this);
		},

		replaceSelection: function () {
			var e = this.jquery ? this[0] : this;
			var text = arguments[0] || '';

			return (
			/* mozilla / dom 3.0 */
				('selectionStart' in e && function () {
					e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length);
					return this;
				})

			/* exploder */
				|| (document.selection && function () {
					e.focus();
					document.selection.createRange().text = text;
					return this;
				})

			/* browser not supported */
				|| function () {
					e.value += text;
					return this;
				}
			)();
		}
	};

	jQuery.each(fieldSelection, function (i) { jQuery.fn[i] = this; });

})();